﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ShowProp
{
    public partial class Form1 : Form
    {
        public class XProp
        {
            // 属性Id，我的项目中需要，大家可以忽略
            private string _id; 
            // 属性所属类别
            private string _category;
            // 属性名称
            private string _name;     
            // 属性的只读性，true为只读
            private bool _readOnly;  
            // 属性的描述内容
            private string _description;
            // 值
            private object _value;    
            // 类型
            private System.Type _type; 
            // 显示或隐藏，true为显示
            private bool _browsable;  
            // 类型转换
            TypeConverter _converter;  
            public XProp()
            {
                _id = "";
                _category = "";
                _name = "";
                _readOnly = false;
                _description = "";
                _value = null;
                _type = null;
                _browsable = true;
                _converter = null;
            }
            public string Id
            {
                get { return _id; }
                set { _id = value; }
            }
            public string Category
            {
                get { return _category; }
                set { _category = value; }
            }
            public bool ReadOnly
            {
                get { return _readOnly; }
                set { _readOnly = value; }
            }
            public string Name
            {
                get { return _name; }
                set { _name = value; }
            }
            public object Value
            {
                get { return _value; }
                set { _value = value; }
            }
            public string Description
            {
                get { return _description; }
                set { _description = value; }
            }
            public System.Type ProType
            {
                get { return _type; }
                set { _type = value; }
            }
            public bool Browsable
            {
                get { return _browsable; }
                set { _browsable = value; }
            }
            public virtual TypeConverter Converter
            {
                get { return _converter; }
                set { _converter = value; }
            }
        }
        private class XPropDescriptor : PropertyDescriptor
        {
            XProp _prop;
            public XPropDescriptor(XProp prop, Attribute[] attrs) : base(prop.Name, attrs)
            {
                _prop = prop;
            }
            public override bool CanResetValue(object component)
            {
                return false;
            }
            public override string Category
            {
                get { return _prop.Category; }
            }
            public override string Description
            {
                get { return _prop.Description; }
            }
            public override TypeConverter Converter
            {
                get { return _prop.Converter; }
            }
            public override System.Type ComponentType
            {
                get { return this.GetType(); }
            }
            public override object GetValue(object component)
            {
                return _prop.Value;
            }
            public override bool IsReadOnly
            {
                get { return _prop.ReadOnly; }
            }
            public override System.Type PropertyType
            {
                get { return _prop.ProType; }
            }
            public override void ResetValue(object component)
            {
            }
            public override void SetValue(object component, object value)
            {
                _prop.Value = value;
            }
            public override bool ShouldSerializeValue(object component)
            {
                return false;
            }
        }
        public class XProps : List<XProp>, ICustomTypeDescriptor
        {
            #region ICustomTypeDescriptor 成员
            public AttributeCollection GetAttributes()
            {
                return TypeDescriptor.GetAttributes(this, true);
            }
            public string GetClassName()
            {
                return TypeDescriptor.GetClassName(this, true);
            }
            public string GetComponentName()
            {
                return TypeDescriptor.GetComponentName(this, true);
            }
            public TypeConverter GetConverter()
            {
                return TypeDescriptor.GetConverter(this, true);
            }
            public EventDescriptor GetDefaultEvent()
            {
                return TypeDescriptor.GetDefaultEvent(this, true);
            }
            public PropertyDescriptor GetDefaultProperty()
            {
                return TypeDescriptor.GetDefaultProperty(this, true);
            }
            public object GetEditor(System.Type editorBaseType)
            {
                return TypeDescriptor.GetEditor(this, editorBaseType, true);
            }
            public EventDescriptorCollection GetEvents(System.Attribute[] attributes)
            {
                return TypeDescriptor.GetEvents(this, attributes, true);
            }
            public EventDescriptorCollection GetEvents()
            {
                return TypeDescriptor.GetEvents(this, true);
            }
            public PropertyDescriptorCollection GetProperties(System.Attribute[] attributes)
            {
                ArrayList props = new ArrayList();
                for (int i = 0; i < this.Count; i++)
                {  //判断属性是否显示
                    if (this[i].Browsable == true)
                    {
                        XPropDescriptor psd = new XPropDescriptor(this[i], attributes);
                        props.Add(psd);
                    }
                }
                PropertyDescriptor[] propArray = (PropertyDescriptor[])props.ToArray(typeof(PropertyDescriptor));
                return new PropertyDescriptorCollection(propArray);
            }
            public PropertyDescriptorCollection GetProperties()
            {
                return TypeDescriptor.GetProperties(this, true);
            }
            public object GetPropertyOwner(PropertyDescriptor pd)
            {
                return this;
            }
            #endregion
            public override string ToString()
            {
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < this.Count; i++)
                {
                    sb.Append("[" + i + "] " + this[i].ToString() + System.Environment.NewLine);
                }
                return sb.ToString();
            }
        }
      
        //重写下拉菜单中的项，使之与属性页的项关联
        public abstract class ComboBoxItemTypeConvert : TypeConverter
        {
            public Hashtable _typeConvertHash = null;
            public ComboBoxItemTypeConvert()
            {
                _typeConvertHash = new Hashtable();
                GetConvertHash();
            }
            public abstract void GetConvertHash();
            //是否支持选择列表的编辑
            public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
            {
                return true;
            }
            //重写combobox的选择列表
            public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
            {
                int[] ids = new int[_typeConvertHash.Values.Count];
                int i = 0;
                foreach (DictionaryEntry myDE in _typeConvertHash)
                {
                    ids[i++] = (int)(myDE.Key);
                }
                return new StandardValuesCollection(ids);
            }
            //判断转换器是否可以工作
            public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
            {
                if (sourceType == typeof(string))
                {
                    return true;
                }
                return base.CanConvertFrom(context, sourceType);

            }
            //重写转换器，将选项列表（即下拉菜单）中的值转换到该类型的值
            public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object obj)
            {
                if (obj is string)
                {
                    foreach (DictionaryEntry myDE in _typeConvertHash)
                    {
                        if (myDE.Value.Equals((obj.ToString())))
                            return myDE.Key;
                    }
                }
                return base.ConvertFrom(context, culture, obj);
            }
            public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
            {
                if (destinationType == typeof(string))
                {
                    return true;
                }
                return base.CanConvertTo(context, destinationType);
            }
            //重写转换器将该类型的值转换到选择列表中
            public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object obj, Type destinationType)
            {
                if (destinationType == typeof(string))
                {
                    foreach (DictionaryEntry myDE in _typeConvertHash)
                    {
                        if (myDE.Key.Equals(obj))
                            return myDE.Value.ToString();
                    }
                    return "";
                }
                return base.ConvertTo(context, culture, obj, destinationType);
            }
            public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
            {
                return false;
            }
        }
        //重写下拉菜单，在这里实现定义下拉菜单内的项
        public class CustomComboItemConvert : ComboBoxItemTypeConvert
        {
            private Hashtable _hash;
            public override void GetConvertHash()
            {
                try
                {
                    _typeConvertHash = _hash;
                }
                catch
                {
                    throw new NotImplementedException();
                }
            }
            public int Value { get; set; }
            public CustomComboItemConvert(string strList)
            {
                _hash = new Hashtable();
                string[] stest = strList.Split(',');
                for (int i = 0; i < stest.Length; i++)
                {
                    _hash.Add(i, stest[i]);
                }
                GetConvertHash();
                Value = 0;
            }
            public CustomComboItemConvert(string strList, int s)
            {
                _hash = new Hashtable();
                string[] stest = strList.Split(',');
                for (int i = 0; i < stest.Length; i++)
                {
                    _hash.Add(i, stest[i]);
                }
                GetConvertHash();
                Value = s;
            }
        }

        public Form1()
        {
            InitializeComponent();
            propertyGrid1.SelectedObject = null;
        }
        private XProps xprops = new XProps();
        private void button1_Click(object sender, EventArgs e)
        {
            XProp newXpro = new XProp();
            newXpro.Category = "公有属性";
            newXpro.Name = "strDemo";
            newXpro.Id = "A";
            newXpro.Description = "用于举例说明";
            newXpro.ReadOnly = false;
            newXpro.Value = "测试属性";
            newXpro.ProType = typeof(string);
            newXpro.Browsable = true;
//            newXpro.Converter = null;

            xprops.Add(newXpro);
            propertyGrid1.SelectedObject = xprops;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            XProps xps = new XProps();
            XProp xprop = new XProp();

            xprop.Name = "姓名";
            xprop.Value = "某人";
            xprop.Category = "人类";
            xprop.Description = "姓甚名谁";
            xprop.ProType = typeof(string);
            xprop.ReadOnly = true;
            xps.Add(xprop);

            xprop = new XProp();
            xprop.Category = "人类";
            xprop.Name = "年龄";
            xprop.ProType = typeof(int);
            xprop.Value = "2";
            xprop.Description = "多大年纪";
            xprop.ReadOnly = false;
            xps.Add(xprop);

            xprop = new XProp();
            xprop.Category = "人类";
            xprop.Name = "性别";
            xprop.Value = 1;
            xprop.ReadOnly = false;
            xprop.ProType = typeof(CustomComboItemConvert);
            xprop.Converter = new CustomComboItemConvert("M,F");
            xprop.Description = "性别是男是女";
            xps.Add(xprop);

            xprop = new XProp();
            xprop.Category = "人类";
            xprop.ReadOnly = false;
            xprop.Name = "国籍";
            xprop.Value = 1;
            xprop.ProType = typeof(CustomComboItemConvert);
            xprop.Converter = new CustomComboItemConvert("中,英,美,法");
            xprop.Description = "国籍";
            xps.Add(xprop);

            xprop = new XProp();
            xprop.Category = "动物";
            xprop.ReadOnly = false;
            xprop.Name = "ABC";
            xprop.Value = 1;
            xprop.ProType = typeof(CustomComboItemConvert);
            xprop.Converter = new CustomComboItemConvert("好的,不好的,法");
            xprop.Description = "CC";
            xps.Add(xprop);

            xprop = new XProp();
            xprop.Category = "能飞";
            xprop.ReadOnly = false;
            xprop.Name = "能飞";
            xprop.Value = 0;
            xprop.ProType = typeof(CustomComboItemConvert);
            xprop.Converter = new CustomComboItemConvert("可以,不可以");
            xprop.Description = "CC";
            xps.Add(xprop);

            propertyGrid1.SelectedObject = xps;
        }
    }
}
